//
// Created by LiuYou on 2021/11/25.
//

#ifndef HTTP_SERVER_EPOLL_HPP
#define HTTP_SERVER_EPOLL_HPP


/**
 * @brief Epoll是工具类。
 *
 * @details 将 epoll的便利函数封装成了一个工具类。同时不会用 Epoll对象 来做什么事情,
 * 所以, 将 Epoll 类的 Big-Five 定义成了 删除的。
 *
 * @since 0.1.1
 * @author ly
 */
class Epoll final {
public:
    Epoll() = delete;

    ~Epoll() = delete;

    Epoll(const Epoll& rhs) = delete;

    Epoll& operator=(const Epoll& rhs) = delete;

    Epoll(Epoll&& rhs) = delete;

    Epoll& operator=(Epoll&& rhs) = delete;

public:
/**
 * @brief 将文件描述符设置为非阻塞, 文件描述符默认是阻塞的。
 * @details 使用了 fcntl();这个管家级别的函数来设置 fd 为非阻塞。
 * <p>加入 static 来修饰函数, 是不想让函数对外扩展。</p>
 * @param fd 传入文件描述符。
 * @return 返回旧的文件描述符的属性。
 *
 * @since 0.1
 * @author ly
 * @date 2021-11-25
 */
    static int setFdNonBlock(int fd);


/* ==================== 布置监视任务 ==================== */

/**
 * @brief 将 fd 加入到 epollFd 中, 来监听事件。可根据需要选择是否开启 EPOLLONESHOT 事件。
 * @details 函数内部使用了 EPOLLET(edge trigger, 边缘触发)模式。
 * @param epollFd 表示 epoll 的文件描述符。
 * @param fd 将 fd 加入到 epoll 树上, 让 epoll 来监听事件。
 * @param isOneShot 是否开启 EPOLLONESHOT 事件。
 *
 * @note <strong>注意:</strong> 调用此函数即, 为 fd 在 epoll 上注册 EPOLLIN | EPOLLET | EPOLLRDHUP 这三个事件。
 * 如果用户开启 EPOLLONESHOT 事件, 那么 调用此函数即, 为 fd 在 epoll 上注册 EPOLLIN | EPOLLET | EPOLLRDHUP | EPOLLONESHOT 。
 *
 * @since 0.1
 * @author ly
 * @date 2021-11-25
 */
    static void addFdToEpoll(int epollFd, int fd, bool isOneShot);

/**
 * @brief 在 epoll 树上删除 fd, 即取消对 fd 监听事件。
 * @param epollFd epoll文件描述符。
 * @param fd 要删除的fd。
 *
 * @since 0.1
 * @author ly
 * @date 2021-11-25
 */
    static void deleteFdFromEpoll(int epollFd, int fd);

/**
 * @brief 修改在 epoll树 上为 fd 监听的事件。
 * @param epollFd epoll文件描述符。
 * @param fd 修改的监听事件的文件描述符。
 * @param epollEvents 修改成想要监听的 epoll事件。
 *
 * @note 注意:
 * <p>调用此函数会修改 fd 的 epoll事件为 参数 epollEvents | EPOLLET | EPOLLONESHOT | EPOLLRDHUP
 * 即默认开启 EPOLLET 模式以及 EPOLLONESHOT 和 EPOLLRDHUP。
 * </p>
 *
 * @since 0.1
 * @author ly
 * @date 2021-11-25
 */
    static void modifyFdFromEpoll(int epollFd, int fd, int epollEvents);

/* ==================== 布置监视任务 ==================== */

};

#endif //HTTP_SERVER_EPOLL_HPP
